//
//  DDropLineViewController.swift
//  Drop
//
//  Created by hushaohua on 2018/2/23.
//  Copyright © 2018年 init. All rights reserved.
//

import UIKit
import CoreData

class DDropLineFooterView:UIView{
    override init(frame: CGRect) {
        super.init(frame: frame);
        self.addSubview(self.startView);
    }
    
    lazy var startView:UIView = {
        var view:UIView = UIView(frame:CGRect(x:79,y:5,width:12,height:12));
        view.backgroundColor = UIColor.darkGray;
        view.layer.cornerRadius = 5;
        view.layer.masksToBounds = true;
        return view;
    }();
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class DDropLineViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {
    
    var beginDate:Date?;
    var endDate:Date?;

    //MARK: - init
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil);
        self.title = "Today";
        let date = Date();
//        self.endDate = Date();
        self.beginDate = date.firstWeekDay(after: 0);
    }
    
    deinit {
       print("dropline deinit")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK:- life cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        self.view.backgroundColor = UIColor.white;
        self.configTableView();
        self.configNavigationItem();
        self.configDropsController();
        self.requestNewest();
    }
    
    //MARK: - tableView
    func configTableView() -> Void{
        self.tableView.tableFooterView = DDropLineFooterView(frame:CGRect(x:0,y:0,width:self.view.bounds.width,height:22));
        self.tableView.rowHeight = 64;
        self.tableView.separatorStyle = .none;
        self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 84, right: 0);
        self.tableView.register(DDropLineTableViewCell.self, forCellReuseIdentifier: DDropLineTableViewCell.normalReuseId);
        self.tableView.register(DDropLineTableViewCell.self, forCellReuseIdentifier: DDropLineTableViewCell.lastReuseId);
        self.tableView.register(DDropLineTableViewCell.self, forCellReuseIdentifier: DDropLineTableViewCell.doingReuseId);
        self.tableView.register(DDropLineTableViewCell.self, forCellReuseIdentifier: DDropLineTableViewCell.lastDoingReuseId);
        self.tableView.register(DDropLineHeaderView.self, forHeaderFooterViewReuseIdentifier: "Header");
        self.view.addSubview(self.tableView);
    }
    
    lazy var tableView:UITableView = {
        var tableView:UITableView = UITableView(frame: self.view.bounds, style: .plain);
        tableView.delegate = self;
        tableView.dataSource = self;
        return tableView;
    }();
    
    //MARK:- drops controller
    func configDropsController() -> Void {
        self.dropsController.delegate = self;
    }
    
    @objc func currentDayDidChanged(_ notification:Notification) -> Void{
        self.requestNewest();
    }
    
    func requestNewest() -> Void{
        do{
            self.configDropsPredicate();
            try self.dropsController.performFetch()
            self.tableView.reloadData();
        }catch{
            let nserror = error as NSError
            fatalError("tags controller fetch error \(nserror), \(nserror.userInfo)")
        }
    }
    
    func configDropsPredicate() -> Void{
        if (self.beginDate != nil && self.endDate != nil){
            let predicate:NSPredicate = NSPredicate(format: "(begin >= %@ AND begin <= %@)", self.beginDate! as NSDate, self.endDate! as NSDate);
            self.dropsController.fetchRequest.predicate = predicate;
        }else if (self.beginDate != nil){
            let predicate:NSPredicate = NSPredicate(format: "(begin >= %@)", self.beginDate! as NSDate);
            self.dropsController.fetchRequest.predicate = predicate;
        }else{
            self.dropsController.fetchRequest.predicate = nil;
        }
    }
    
    //MARK:- NSFetchedResultsController
    lazy var dropsController:NSFetchedResultsController<Drop> = {
        let request:NSFetchRequest = Drop.defaultFetchRequest();
        request.sortDescriptors = [NSSortDescriptor(key: "begin", ascending: false)];
        request.propertiesToFetch = ["begin", "end", "tag"];
        request.includesSubentities = false;
        
        var controller:NSFetchedResultsController<Drop> = NSFetchedResultsController(fetchRequest: request, managedObjectContext: HStoreManager.defaultManger().context, sectionNameKeyPath: "dateString", cacheName: nil);
        return controller;
    }();
    
    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self.tableView.beginUpdates();
    }
    
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self.tableView.endUpdates();
    }
    
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch type {
        case .insert:
            self.tableView.insertRows(at: [newIndexPath!], with: .automatic);
        case .delete:
            self.tableView.deleteRows(at: [indexPath!], with: .automatic);
        case .update:
            self.tableView.reloadRows(at: [indexPath!], with: .automatic);
        default:
            break;
        }
    }
    //MARK:- tableView
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if (cell.reuseIdentifier! == DDropLineTableViewCell.doingReuseId || cell.reuseIdentifier! == DDropLineTableViewCell.lastDoingReuseId){
            (cell as! DDropLineTableViewCell).startBright();
        }
    }
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if (cell.reuseIdentifier! == DDropLineTableViewCell.doingReuseId || cell.reuseIdentifier! == DDropLineTableViewCell.lastDoingReuseId){
            (cell as! DDropLineTableViewCell).stopBright();
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if (indexPath.row != self.dropsController.sections![indexPath.section].numberOfObjects - 1){
            return 64;
        }else{
            return 44;
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.dropsController.sections != nil ? self.dropsController.sections!.count : 0;
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.dropsController.sections![section].numberOfObjects;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let drop:Drop = self.dropsController.object(at: indexPath) as Drop;
        
        var reuseId = DDropLineTableViewCell.normalReuseId;
        var timeString:String? = nil;
        var titleString:String? = nil;
        
        if (indexPath.row != self.dropsController.sections![indexPath.section].numberOfObjects - 1){//非最后一个
            let dayFormatter:DateFormatter = DateFormatter();
            dayFormatter.dateFormat = "HH:mm";
            timeString = dayFormatter.string(from: drop.begin! as Date);
        }else if (drop.tag == nil || drop.end == nil){//最后一个而且正在进行
            reuseId = DDropLineTableViewCell.lastDoingReuseId;
        }else{
            reuseId = DDropLineTableViewCell.lastReuseId;
        }
        if (drop.tag != nil && drop.end != nil){
            var durationString:String = "";
            let interval:Int = Int(drop.end!.timeIntervalSince(drop.begin! as Date));
            if (interval < 60){
                durationString = "1'";
            }else if (interval < 3600){
                durationString = "\(interval / 60)'";
            }else{
                durationString = "\(interval / 3600):\((interval % 3600)/60)'";
            }
            titleString = "\(drop.tag!.name)(\(durationString))";
            if (drop.hideNote || drop.note == nil){
                titleString = "\(drop.tag!.name)(\(durationString))";
            }else{
                titleString = "\(drop.tag!.name)(\(timeString!))\n\(drop.note!)";
            }
        }else if (reuseId != DDropLineTableViewCell.lastDoingReuseId){
            reuseId = DDropLineTableViewCell.doingReuseId;
        }
        
        let cell:DDropLineTableViewCell = tableView.dequeueReusableCell(withIdentifier: reuseId, for: indexPath) as! DDropLineTableViewCell;
        cell.marginLeftOffset = 22;
        cell.selectionStyle = .none;
        if (titleString != nil){
            cell.titleLabel?.text = titleString;
        }
        if (timeString != nil){
            cell.beginDateLabel?.text = timeString;
        }
        weak var weakSelf = self;
        cell.customRevokeClosure = {(aCell) in
            weakSelf?.revokeAction(aCell);
        };
        cell.customModifyTagClosure = {(aCell) in
            weakSelf?.modifyTagAction(aCell);
        };
        cell.shouldRevoke = { (aCell) in
            return weakSelf != nil ? weakSelf!.shouldRevokeFor(aCell) : false;
        };
        cell.shouldModifyTag = {(aCell) in
            return weakSelf != nil ? weakSelf!.shouldModifyTagFor(aCell) : false;
        };
        cell.updateNoteClosure = {(aCell) in
            weakSelf?.updateNoteAction(aCell);
        };
        cell.tapTitleClosure = {(aCell) in
            weakSelf?.tapTitleAction(aCell);
        };
        
        return cell;
    }
    func updateNoteAction(_ cell:UITableViewCell) -> Void {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let window = UIApplication.shared.keyWindow!;
            let dropCell:DDropLineTableViewCell = cell as! DDropLineTableViewCell;
            let tagFrame = dropCell.titleLabel!.convert(dropCell.titleLabel!.bounds, to: window);
            let beginFrame = dropCell.beginDateLabel!.convert(dropCell.beginDateLabel!.bounds, to: window);
            var endFrame = beginFrame;
            let cellY = dropCell.convert(dropCell.bounds.origin, to: window).y;
            endFrame.origin.y = cellY - beginFrame.size.height;
            
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            let controller = DDropNoteViewController();
            controller.sourceBeginDateFrame = beginFrame;
            controller.sourceEndDateFrame = endFrame;
            controller.sourceTagFrame = tagFrame;
            controller.modalPresentationStyle = .overCurrentContext;
            controller.drop = drop;
            weak var weakSelf = self;
            controller.didUpdateDropNote = {
                weakSelf?.tableView.reloadRows(at: [indexPath!], with: .automatic);
            };
            self.present(controller, animated: false, completion: nil);
        }
    }
    func tapTitleAction(_ cell:UITableViewCell) {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            if (drop.note != nil){
                drop.hideNote = !drop.hideNote;
                self.tableView.reloadRows(at: [indexPath!], with: .automatic);
            }else{
                drop.hideNote = true;
            }
        }
    }
    
    func shouldRevokeFor(_ cell:UITableViewCell) -> Bool {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            if (drop.tag != nil && drop.end != nil){
                let interval = Date().timeIntervalSince(drop.end! as Date);
                if (interval < 120 && indexPath!.section == 0 && indexPath!.row == 1){
                    return true;
                }
            }
        }
        return false;
    }
    func shouldModifyTagFor(_ cell:UITableViewCell) -> Bool {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            if (drop.tag != nil && drop.end != nil){
                let interval = Date().timeIntervalSince(drop.end! as Date);
                if (interval < 120){
                    return true;
                }
            }
        }
        return false;
    }
    func revokeAction(_ cell:UITableViewCell) -> Void {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            DDroppingManager.sharedManager().revokeLatestDrop(drop);
        }
    }
    
    func modifyTagAction(_ cell:UITableViewCell) -> Void {
        let indexPath:IndexPath? = self.tableView.indexPath(for: cell);
        if (indexPath != nil){
            let drop:Drop = self.dropsController.object(at: indexPath!) as Drop;
            DDroppingManager.sharedManager().gotoDropInto(drop);
        }
    }
    
    func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
        return true;
    }

    func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
        return true;
    }

    func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {

    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 22;
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view:DDropLineHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header") as! DDropLineHeaderView;
        view.contentView.backgroundColor = UIColor.clear;
        view.timeLabel.text = self.dropsController.sections![section].name;
        return view;
    }
    
    //MARK: - navigation
    func configNavigationItem() -> Void{
        let button = UIBarButtonItem(customView: self.filterButton());
        self.navigationItem.rightBarButtonItem = button;
        self.navigationItem.titleView = self.titleView();
        self.subTitleLabel.text = DPreferences.defaultPreferences().timelineAnalysis.analysisDescription();
    }
    
    func filterButton() -> UIButton{
        let button = UIButton(frame: CGRect(x:0,y:0,width:44,height:44));
        button.contentHorizontalAlignment = .right;
        button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .light);
        button.setTitle("设置", for: .normal);
        button.setTitleColor(UIColor.darkGray, for: .normal);
        button.addTarget(self, action: #selector(changeDate), for: .touchUpInside);
        return button;
    }
    @objc func changeDate() -> Void{
        weak var weakSelf = self;
        let controller = DAnalysisDatePreferenceViewController();
        controller.analysis = DPreferences.defaultPreferences().timelineAnalysis.copy();
        controller.doneClosure = { (analysis) in
            DPreferences.defaultPreferences().timelineAnalysis = analysis;
            weakSelf?.beginDate = analysis.queryBeginDate();
            if (analysis.intervalValue.subType != .Custom){
                weakSelf?.endDate = nil;
            }else{
                weakSelf?.endDate = analysis.queryEndDate();
            }
            
            weakSelf?.requestNewest();
            weakSelf?.subTitleLabel.text = DPreferences.defaultPreferences().timelineAnalysis.analysisDescription();
            weakSelf?.navigationController?.popViewController(animated: true);
        };
        self.navigationController?.pushViewController(controller, animated: true);
    }
    
    func titleView() -> UIView{
        let view = UIView(frame: CGRect(x:0,y:0,width:200,height:44));
        view.addSubview(self.titleLabel());
        view.addSubview(self.subTitleLabel);
        return view;
    }
    
    func titleLabel() -> UILabel{
        let label:UILabel = UILabel(frame: CGRect(x:0,y:6,width:200,height:24));
        label.autoresizingMask = [.flexibleWidth];
        label.text = "时间线";
        label.font = UIFont.systemFont(ofSize: 18);
        label.textAlignment = .center;
        label.textColor = UIColor.black;
        return label;
    }
    
    lazy var subTitleLabel:UILabel = {
        var label:UILabel = UILabel(frame: CGRect(x:0,y:30,width:200,height:12));
        label.autoresizingMask = [.flexibleWidth];
        label.text = "本周";
        label.font = UIFont.systemFont(ofSize: 10, weight: .light);
        label.textAlignment = .center;
        label.textColor = UIColor.gray;
        return label;
    }();
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}
